#include "../apue.h"
#include "../ftp.h"

void udp_send(struct ftp_info cli_send_to_ser,char *ip)
{
	int sockfd;
	int n;
	struct sockaddr_in toaddr;
	int len = sizeof(toaddr);
	
	sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if(sockfd < 0)
	{
		perror("socket");
		exit(1);
	}

	bzero(&toaddr, sizeof(toaddr));
	toaddr.sin_family = AF_INET;
	toaddr.sin_port = htons(6111);    
	toaddr.sin_addr.s_addr = inet_addr(ip);

	sendto(sockfd, &cli_send_to_ser, sizeof(cli_send_to_ser), 0, 
					(struct sockaddr *)&toaddr, len);
	perror("sendto");
	
	return ;
}

void login(char *ip, struct ftp_info cli_send_to_ser)
{
	char user_name[50] = {'\0'};
	char passwd[50] = {'\0'};
	//struct ftp_login login;
	printf("please input user name :");
	scanf("%s", user_name);
	printf("please input passwd :");
	scanf("%s", passwd);
	strcpy(cli_send_to_ser.cmd_arg.login.login_user, user_name);
	strcpy(cli_send_to_ser.cmd_arg.login.login_passwd, passwd);
	udp_send(cli_send_to_ser, ip);
}

void tcp_send(char *buffer, char *ip)
{
	int sockfd;
	struct sockaddr_in toaddr;
	int ret;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
	{
		perror("socket");
		exit(1);
	}

	bzero(&toaddr, sizeof(toaddr));
	toaddr.sin_family = AF_INET;
	toaddr.sin_port = htons(1234);
	toaddr.sin_addr.s_addr = inet_addr( ip );
		
	ret = connect(sockfd, (struct sockaddr *)&toaddr, sizeof(toaddr));
	if(ret < 0)
	{
		perror("connect");
		exit(1);
	}
	write(sockfd, buffer, strlen(buffer) + 1);
	perror("write");

	return ;

}

struct execute_result tcp_rec(struct execute_result rec_data, char *ip)
{
	int sockfd;
	struct sockaddr_in toaddr;
	int ret;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
	{
		perror("socket");
		exit(1);
	}

	bzero(&toaddr, sizeof(toaddr));
	toaddr.sin_family = AF_INET;
	toaddr.sin_port = htons(1234);
	toaddr.sin_addr.s_addr = inet_addr( ip );
		
	ret = connect(sockfd, (struct sockaddr *)&toaddr, sizeof(toaddr));
	if(ret < 0)
	{
		perror("connect");
		exit(1);
	}

	recv(sockfd, &rec_data, sizeof(rec_data), 0);

	return rec_data;

}

int main(int argc, char **argv)
{
	struct execute_result rec_data;
	struct ftp_info cli_send_to_ser;
	struct ftp_login login_info;
	char buffer[256];
	int pid_1, pid_2;
	char ip[64];
	char cmd[64];
	int clipid;
	char pathname[100];

	memset(&rec_data, 0, sizeof(rec_data));
	memset(&cli_send_to_ser, 0, sizeof(cli_send_to_ser));
	memset(&login_info, 0, sizeof(login_info));
	if(argc != 2)
	{
		printf("%s ip_addr \n", argv[0]);
		exit(0);
	}
	
	memset(&buffer, 0, sizeof(buffer));
	gets(buffer);
	strcpy(ip, argv[1]);
	clipid = getpid();
	cli_send_to_ser.cli_pid = clipid;
	//cli_send_to_ser.login_info;
	/*login ftp*/
	//login(ip, cli_send_to_ser);
	
	/*
	 *if you login successfully,you will create a child process to send command;
	 *and parent process will receive return info,or put info to server.
	*/	
	pid_2 = fork();
	if(pid_2 < 0)
	{
		perror("fork");
		exit(0);
	}
	/*
	 * you create a process to send command.
	*/
	if(pid_2 == 0)
	{
		while(1)
		{
			/*send to server info include : cmd, pathname, cli_pid*/
			memset(buffer, 0, sizeof(buffer));
			gets(buffer);
			sscanf(buffer, "%s %s", cmd, pathname);
			if(atoi(cmd) == 1)
			{
				login(ip, cli_send_to_ser);
			}
			else
			{
				cli_send_to_ser.ftp_cmd = atoi(cmd);
				//cli_send_to_ser.cmd_arg.cmd_pathname = pathname;
				strcpy(cli_send_to_ser.cmd_arg.cmd_pathname, pathname);
				cli_send_to_ser.cli_pid = clipid;
				udp_send(cli_send_to_ser, ip);
			}
		}
	
	}
	/*
	 *after child process,parent process receive info from server;
	 *
	*/
	else
	{
		/*if cmd is PUT,you should put information rely on tcp_send()*/
		if(atoi(cmd) == 7)
		{
			int fid;
			int n;
			fid = open(pathname, O_RDONLY);
			if(fid < 0)
			{
				printf("open file error ,please open again");
				exit(1);
			}
			while(1)
			{
				bzero(buffer, sizeof(buffer));
				n = read(fid, buffer, sizeof(buffer));
				if(n <= 0)
				{
					break;
				}
				tcp_send(buffer, ip);
			}
		}
		/*if some cmd else, you should receive info rely on tcp_rec()*/
		else
		{
			bzero(&rec_data, sizeof(rec_data));
			rec_data = tcp_rec(rec_data, ip);
			/*flag = 1, receive a file , should create a file and save it*/
			if(rec_data.flag == 1)
			{
				char *fname;
				int fid;
				fname = basename(pathname);
				fid = open(fname, O_CREAT | O_EXCL | O_WRONLY);
				write(fid, rec_data.execute_data, sizeof(rec_data.execute_data));
				while(1)
				{
					memset(&rec_data, 0, sizeof(rec_data));
					rec_data = tcp_rec(rec_data, ip);
					write(fid, rec_data.execute_data, sizeof(rec_data.execute_data));
					if(strlen(rec_data.execute_data) == 0)
					{
							break;
					}
				}
			}
			/*flag = 0, receive some info,should stdout.*/
			else
			{
				write(1, rec_data.execute_data, strlen(rec_data.execute_data) + 1);
			}
		}
	}

	return 0;
}
